/*******************************************************************************
* @file     sd card task
* @version  V1.00
*******************************************************************************/
#include "ff.h"
#include "sys_task.h"
#include "bsp_api.h"
#include "os_obj.h"

/*****************************************************************************
* @brief   const 
*****************************************************************************/

/*****************************************************************************
* @brief   function
*****************************************************************************/
uu8 sd_fat_scan_files(char *path);

/*****************************************************************************
* @brief   extern var
*****************************************************************************/
extern SD_HandleTypeDef hsd;

/*****************************************************************************
* @brief   loacal var
*****************************************************************************/
TCHAR sd_path[] = {'0', ':', 0}; /* SD drive started from 0 */

struct sdfat_str
{
	FIL fil;
	FRESULT fst;
	DIR dir;
	FATFS fat;
	FILINFO finfo;
	UINT len_back;
} sdf;

/*****************************************************************************
* @brief   sd_task.
* @param   argument
* @return  none
*****************************************************************************/
void sd_task(void *argument)
{

	uint8_t cd = 0;
	osDelay(ms_ticks(1000));

	while (1)
	{
		osDelay(ms_ticks(10));
		if (cd != sys_st.bios.sd_cd.st)
		{
			uu8 *buff;
			uu16 rd_cnt;

			buff = malloc(1024 * 2 + 16);

			cd = sys_st.bios.sd_cd.st;
			if (sys_st.bios.sd_cd.st)
			{
				HAL_SD_DeInit(&hsd);
				__HAL_RCC_SDIO_CLK_ENABLE();
				__HAL_RCC_SDIO_FORCE_RESET();
				__HAL_RCC_SDIO_RELEASE_RESET();
				HAL_SD_Init(&hsd);
				if(HAL_SD_Init(&hsd) != HAL_OK)
				{
					file_dbg_puts("sd init fail !\n");
				}
				
				file_dbg_puts("sd insert, read file list in root :\n");

				f_mount(&sdf.fat, "0:", 1);

				// path
				sdf.fst = f_chdrive(sd_path);

				if (sdf.fst == FR_OK)
				{
					sd_fat_scan_files("/");
				}
				else
				{
					file_dbg_puts("ch diver fail \n");
				}

				sdf.fst = f_open(&sdf.fil, "MBED0.BIN", FA_READ);

				if (sdf.fst == FR_OK)
				{
					uu32 tm_start = app_tick_get();

					for (rd_cnt = 0; rd_cnt < 1024; rd_cnt++)
					{
						f_lseek(&sdf.fil, 0);
						sdf.fst = f_read(&sdf.fil, buff, 2048, &sdf.len_back);
						if (sdf.fst != FR_OK)
						{
							break;
						}
					}

					file_dbg_print("read cnt %4d, data amount : %dKB, time used: %dms \n",
								   rd_cnt, rd_cnt * 2, app_tick_get() - tm_start);

					//buff[sdf.len_back] = 0;
					//file_dbg_puts((char *)buff);
				}

				f_close(&sdf.fil);

				f_mount(0, "0:", 1);
			}
			else
			{
				file_dbg_puts("sd card removed !\n");
			}
			free(buff);
		}
	}
}

/*****************************************************************************
* @brief   mf_scan_files
* @param   path
* @return  none
* @ Pass/ Fail criteria: none
*****************************************************************************/
uu8 sd_fat_scan_files(char *path)
{
	FRESULT res;
	char *fn; /* This function is assuming non-Unicode cfg. */
	int16_t site, pdf_cnt = 0;

#if _USE_LFN
	//sdf.finfo.lfsize = _MAX_LFN * 2 + 1;
	//sdf.finfo.lfname = malloc(sdf.finfo.lfsize);
#endif

	res = f_opendir(&sdf.dir, (const char *)path);

	if (res == FR_OK)
	{
		while (1)
		{
			res = f_readdir(&sdf.dir, &sdf.finfo);

			if (res != FR_OK || sdf.finfo.fname[0] == 0)
				break;

#if _USE_LFN
			//fn = *sdf.finfo.lfname ? sdf.finfo.lfname : sdf.finfo.fname;
			fn = sdf.finfo.fname;
#else
			fn = sdf.finfo.fname;
#endif /* It is a file. */
			if (sdf.finfo.fattrib & AM_DIR)
			{
				file_dbg_print("fonund dir %s \n", fn);
			}
			else
			{
				file_dbg_print("fonund file %s \n", fn);
				site = str_nsearch_ch(fn, '.');

				if (site > 0)
				{
					if (0 == comp_string((void *)&fn[site], (void *)".PDF\0", 5))
					{
						pdf_cnt++;
					}
				}
			}
		}

		file_dbg_print("fonund pdf file amount : %d \n", pdf_cnt);
	}
	else
	{
		file_dbg_puts("open dir fail !\n");
	}

	return res;
}